﻿using System;
using Abp.AspNetCore;
using Abp.Castle.Logging.Log4Net;
using Abp.EntityFrameworkCore;
using Ny.CenterServers.EntityFrameworkCore;
using Castle.Facilities.Logging;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Swashbuckle.AspNetCore.Swagger;
using Ny.CenterServers.Web.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.Threading.Tasks;
using System.Linq;
using Ny.CenterServers.Web.Utils;
using System.IO;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;
using Ny.Ci.EntityFrameworkCore.EntityFrameworkCore;
using Ny.CenterServers.Configuration;

namespace Ny.CenterServers.Web.Startup
{
    public class Startup
    {
        private readonly IConfigurationRoot _appConfiguration;

        public Startup(IHostingEnvironment env)
        {
            _appConfiguration = AppConfigurations.Get(env.ContentRootPath, env.EnvironmentName);
        }

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            //配置 DbContext
            //总项目dbcontext connection
            services.AddAbpDbContext<CenterServersDbContext>(options =>
            {
                DbContextOptionsConfigurer.Configure(options.DbContextOptions, _appConfiguration.GetConnectionString("Default"));
            });

            //ci积分服务的dbcontext
            services.AddAbpDbContext<CiDbContext>(options =>
            {
                CiDbContextOptionsConfigurer.Configure(options.DbContextOptions, _appConfiguration.GetConnectionString("CiConnectString"));
            });
            services.Configure<JwtSettings>(_appConfiguration.GetSection("JwtSettings"));
            JwtSettings setting = new JwtSettings();
            _appConfiguration.Bind("JwtSettings", setting);
            services.AddAuthentication(option =>
            {
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(config =>
         {
                 /*
config.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
   ValidAudience = setting.Audience,
   ValidIssuer = setting.Issuer,
   IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecretKey))
};
*/
    config.SecurityTokenValidators.Clear();
    config.SecurityTokenValidators.Add(new MyTokenValidate());
    config.Events = new JwtBearerEvents()
    {
        OnMessageReceived = context =>
                     {
                            var token = context.Request.Headers["jwtToken"];
                            context.Token = token.FirstOrDefault();
                            return Task.CompletedTask;
                        }

    };
});

            services.AddMvc(options =>
            {
                options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
            });
            //配置swaggerUI
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info
                {
                    Version = "v1",
                    Title = "NY API",
                    Description = "奶业集团项目的API描述文档",
                });
                options.SwaggerDoc("CiApi", new Info { Title = "ci系统服务api", Version = "CiApi" });
                options.DocInclusionPredicate((docName, description) => true);
                options.DocInclusionPredicate((docName,description)=> {
                    if (!description.TryGetMethodInfo(out MethodInfo methodInfo)) return false;
                    var versions = methodInfo.DeclaringType.GetCustomAttributes(true).OfType<ApiExplorerSettingsAttribute>().Select(attr=>attr.GroupName);
                    if (docName.ToLower() == "v1" && versions.FirstOrDefault() == null)
                    {
                        return true;
                    }
                    return versions.Any(v=>v.ToString()==docName);
                });





                var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
                //配置接口注释（项目属性输出要启用xml文档文件）
                var commentsFileName = "Ny.CenterServers.Application.xml";
                var commentsFile = Path.Combine(baseDirectory, commentsFileName);
                //ci注释文档
                var commentsFileName_Ci = "Ny.Ci.Application.xml";
                var commentsFile_Ci = Path.Combine(baseDirectory, commentsFileName_Ci);
                //将注释的XML文档添加到SwaggerUI中
                options.IncludeXmlComments(commentsFile);
                options.IncludeXmlComments(commentsFile_Ci);
                options.OperationFilter<HttpHeaderOperation>(); // 添加httpHeader参数
                //var basePath = AppContext.BaseDirectory;
                //var xmlPath = Path.Combine(basePath, "CMS_Web_API.xml");
                //options.IncludeXmlComments(xmlPath);
            });

            //Configure Abp and Dependency Injection
            return services.AddAbp<CenterServersWebModule>(options =>
            {
                //Configure Log4Net logging
                options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                    f => f.UseAbpLog4Net().WithConfig("log4net.config")
                );
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.UseAbp(); //Initializes ABP framework.

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();
            //授权验证
            app.UseAuthentication();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

            //使用swagger
            app.UseSwagger();
            app.UseSwaggerUI(action =>
            {
                action.SwaggerEndpoint("/swagger/v1/swagger.json", "ny");
                action.SwaggerEndpoint("/swagger/CiApi/swagger.json", "CiApi");
            });
        }
    }
}
